package com.enation.app.javashop.core.app;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.enation.app.javashop.core.app.model.PushNotice;
import com.enation.app.javashop.core.base.SettingGroup;
import com.enation.app.javashop.core.base.service.SettingManager;
import com.enation.app.javashop.core.system.model.vo.AppPushSetting;
import com.enation.app.javashop.framework.util.EnvironmentUtils;
import com.enation.app.javashop.framework.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import sun.misc.BASE64Encoder;

import java.util.ArrayList;
import java.util.List;

/**
 * 极光推送工具类
 */
@Slf4j
@Component
public class JPushService {

    // 请求地址
    //@Value("${jpush.url}")
    private String url = "https://api.jpush.cn/v3/push";
    // appKey
    //@Value("${jpush.app_key}")
    private String appKey = "";
    // secret秘钥
    //@Value("${jpush.secret}")
    private String secret = "";

    //与前端一致的别名前缀
    private final String  prefix="mkt_s_";

    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired(required = false)
    private RestTemplate restTemplate;
    @Autowired
    private SettingManager settingManager;

    /**
     * 极光推送的接口
     * @param pushNotice
     */
    public void jpush(PushNotice pushNotice) {
        //获取推送的appKey和secret秘钥
        String appPushSettingJson = settingManager.get(SettingGroup.PUSH);
        AppPushSetting appPushSetting = JsonUtil.jsonToObject(appPushSettingJson, AppPushSetting.class);
        appKey = appPushSetting.getAndroidPushKey();
        secret = appPushSetting.getAndroidPushSecret();
        //获取jpush链接
        JPushClient jpushClient = new JPushClient(secret, appKey);

        String[] platformType = pushNotice.getPlatform();
        //推送哪些客户端
        Platform platform ;
        boolean state = true;//推送到所有平台
        if (platformType.length == 1 && !platformType.equals("")) {
            if (platformType[0].equals("ios")) {
                platform = Platform.ios();
                state = false;
            } else if (platformType[0].equals("android")) {
                platform = Platform.android();
                state = false;
            } else {
                platform = Platform.all();
            }
        } else {
            platform = Platform.all();
        }
        String[] audiences = pushNotice.getAudience();
        try {
            //推送限制一次只能推1000条，如果大于1000，则多次调用推送方法
            if (audiences.length >= 1000) {
                List<String> arrayList=new ArrayList<>();
                for (int i = 1; i <= audiences.length; i++) {
                    arrayList.add(prefix + audiences[i-1]);
                    if (i % 1000 == 0) {
                        realPush(jpushClient,pushNotice,arrayList,state,platform);
                        arrayList.removeAll(arrayList);
                    }
                }
            } else {
                List<String> arrayList=new ArrayList<>();
                for (int i = 0; i < audiences.length; i++) {
                    arrayList.add(prefix + audiences[i]);
                }
                realPush(jpushClient,pushNotice,arrayList,state,platform);
            }
        } catch (APIConnectionException e) {
            logger.error("Connection error. Should retry later. " + e);
        } catch (APIRequestException e) {
            logger.error("Error response from JPush server. Should review and fix it. " + e);
            logger.error("HTTP Status: " + e.getStatus());
            logger.error("Error Code: " + e.getErrorCode());
            logger.error("Error Message: " + e.getErrorMessage());
        } finally {
            jpushClient.close();
        }
    }

    /**
     * 实际推送的方法
     *
     * @param jpushClient jpush的连接
     * @param pushNotice 推送的信息
     * @param alias 推送给谁
     * @param state 是否全平台推送 false为只推送安卓
     * @param platform
     * @throws APIConnectionException
     * @throws APIRequestException
     */
    private void realPush(JPushClient jpushClient, PushNotice pushNotice,List<String> alias, boolean state,Platform platform) throws APIConnectionException, APIRequestException {
        PushPayload payload;
        if (state) {
            //推送所有平台
            payload = PushPayload.newBuilder()
                    .setPlatform(platform)//推送的平台
                    .setAudience(Audience.alias(alias))//使用别名推送  Audience.alias("mkt_s_29")
                    .setNotification(Notification.newBuilder()
                            .addPlatformNotification(
                                    AndroidNotification.newBuilder()//安卓推送设置
                                            .setAlert(pushNotice.getContent())//显示的内容
                                            .setTitle(pushNotice.getTitle())//显示的是这个标题
                                            .addExtra("type", pushNotice.getType())//type是需要跟前端约定的参数名
                                            .build())
                            .addPlatformNotification(
                                    IosNotification.newBuilder()//Ios推送设置
                                            .setAlert(pushNotice.getContent())
                                            .addExtra("type", pushNotice.getType()) //type要和前端一致
                                            .build())
                            .build())
                    // .setMessage(Message.newBuilder().setTitle(title).setMsgContent("application/json").setMsgContent(content).build())
                    .setOptions(Options.newBuilder().setApnsProduction(EnvironmentUtils.isProd()).build())//state=true表示推送到正式服务器，为false表示推送到测试服务器
                    .build();
        } else {
            //推送安卓平台
            payload = PushPayload.newBuilder()
                    .setPlatform(platform)//推送的平台
                    .setAudience(Audience.alias(alias))//使用别名推送  Audience.alias("mkt_s_29")
                    .setNotification(Notification.newBuilder()
                            .addPlatformNotification(
                                    AndroidNotification.newBuilder()//安卓推送设置
                                            .setAlert(pushNotice.getContent())//显示的内容
                                            .setTitle(pushNotice.getTitle())//显示的是这个标题
                                            .addExtra("type", pushNotice.getType())
                                            .build())
                            .build())
                    // .setMessage(Message.newBuilder().setTitle(title).setMsgContent("application/json").setMsgContent(content).build())
                    .setOptions(Options.newBuilder().setApnsProduction(EnvironmentUtils.isProd()).build())//state=true表示推送到正式服务器，为false表示推送到测试服务器
                    .build();
        }

        //推送
        PushResult result = jpushClient.sendPush(payload);
        if (result.statusCode != 0) {
            logger.error("推送消息失败!");
        }

    }


    /**
     * 极光推送： Rest-api推送使用
     *
     * @param pushNotice 推送参数JSON格式
    // * @param tags       要推送的标签
     * @return
     */
    // public String push(PushNotice pushNotice) {
    //     HttpHeaders headers = new HttpHeaders();
    //     headers.setContentType(MediaType.APPLICATION_JSON);
    //     String authorization = getAuthorization(appKey, secret);
    // headers.setBasicAuth(authorization, "XXXXXXXXXXXXXXXXXXXXXXX");
    // headers.setBasicAuth(appKey, secret);
    // String[] tags;
    // if (tags.length > 0) {
    //     int count = tags.length % 20;
    //     int s = count > 0 ? count + 1 : count;
    //     int pre=0;//截取数组的初始位置
    //     for (int j = 0; j < s; j++) {
    //
    //     }
    // }
    // PushNotice pushNotice1= PushNotice.byTag(pushNotice.getMessage().getTitle(), pushNotice.getMessage().getContent_type(),
    //         "测试", pushNotice.getMessage().getMsg_content());
    // Notification no=new Notification();
    // no.setAlert("测试标题");
    // no.setAndroid(JSON.parseObject(""));
    // pushNotice1.setNotification(no);
    // String jsonParam = convertToJson(pushNotice1);
    // pushNotice.getAudience().getTag().toString()
    //     String jsonParam = convertToJson(pushNotice1);
    //     log.info("极光JPusher:" + url + "请求报文：" + jsonParam);
    //     HttpEntity<PushNotice> requestEntity = new HttpEntity<>(pushNotice1, headers);
    //     ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
    //     String result = responseEntity.getBody();
    //     log.info("极光JPusher:" + url + "响应报文：" + result);
    //     return result;
    // }

    /**
     * 将PushNotice进行转化处理
     */
    // private String convertToJson(PushNotice pushNotice) {
    //     JSONObject object = new JSONObject();
    //     if (StringUtils.isBlank(pushNotice.getCid())) {
    //         throw new ServiceException("500", "cid为空");
    //     }
    //     if (null == pushNotice.getAudience()) {
    //         throw new ServiceException("500", "设备信息为空");
    //     }
    //     if (null == pushNotice.getNotification()
    //             && null == pushNotice.getMessage()) {
    //         throw new ServiceException("500", "通知或消息不能都为空");
    //     }
    //     object.put("cid", pushNotice.getCid());
    //     if (null == pushNotice.getPlatform()) {
    //         object.put("platform", "all");
    //     } else {
    //         object.put("platform", pushNotice.getPlatform());
    //     }
    //     if (null == pushNotice.getAudience()) {
    //         object.put("audience", "all");
    //     } else {
    //         object.put("audience", pushNotice.getAudience());
    //     }
    //     if (null != pushNotice.getNotification()) {
    //         object.put("notification", pushNotice.getNotification());
    //     }
    //     if (null != pushNotice.getMessage()) {
    //         object.put("message", pushNotice.getMessage());
    //     }
    //     if (null != pushNotice.getCallback()) {
    //         object.put("callback", pushNotice.getCallback());
    //     }
    //     if (null != pushNotice.getOptions()) {
    //         object.put("options", pushNotice.getOptions());
    //     }
    //     return JSONObject.toJSON(object).toString();
    // }

    /**
     * BASE64加密工具
     */
    private String encryptBASE64(String content) {
        byte[] key = content.getBytes();
        BASE64Encoder base64Encoder = new BASE64Encoder();
        return base64Encoder.encodeBuffer(key);
    }

    /**
     * 根据appKey|masterSecret 加密后生成token
     */
    private String getAuthorization(String appKey, String masterSecret) {
        return encryptBASE64(appKey + ":" + masterSecret);
    }
}
